package ua.yandex.shad.tempseries;

import static java.lang.Math.abs;
import static java.lang.Math.pow;
import java.util.ArrayList;

public class TemperatureSeriesAnalysis {

    public class IllegalTemperatureValueException extends Exception {

        public IllegalTemperatureValueException(String message) {
            super(message);
        }

    }

    private final double[] temperatureSeries;

    public TemperatureSeriesAnalysis(double[] temperatureSeries) {
        this.temperatureSeries = temperatureSeries;
    }

    private boolean checkCorrect() {
        for (int i = 0; i < temperatureSeries.length; i++) {
            if (temperatureSeries[i] < -273) {
                return false;
            }
        }
        return true;
    }

    public double calcAverageTemp() throws IllegalTemperatureValueException {
        if (!checkCorrect()) {
            throw new IllegalTemperatureValueException("Temperature cannot be less than -273C");
        }
        double av = 0;
        for (int i = 0; i < temperatureSeries.length; i++) {
            av += temperatureSeries[i];
        }
        av /= temperatureSeries.length;
        return av;
    }

    public double calcTempDeviation() throws IllegalTemperatureValueException {
        double av = calcAverageTemp();
        double dev = 0;
        for (int i = 0; i < temperatureSeries.length; i++) {
            dev += pow(temperatureSeries[i] - av, 2);
        }
        dev /= temperatureSeries.length;
        return dev;
    }

    public double findTempClosestToZero() throws IllegalTemperatureValueException {
        return findTempClosestToValue(0);
    }

    public double findTempClosestToValue(double tempValue) throws IllegalTemperatureValueException {
        if (!checkCorrect()) {
            throw new IllegalTemperatureValueException("Temperature cannot be less than -273C");
        }
        if (temperatureSeries.length == 0) {
            return 0;
        }
        double closest = temperatureSeries[0];
        for (int i = 1; i < temperatureSeries.length; i++) {
            if (abs(tempValue - temperatureSeries[i]) < abs(closest - tempValue)
                    || (abs(tempValue - temperatureSeries[i]) == abs(closest - tempValue)
                    & temperatureSeries[i] > closest)) {
                closest = temperatureSeries[i];
            }
        }
        return closest;
    }

    public double[] findTempsLessThen(double tempValue) throws IllegalTemperatureValueException {
        if (!checkCorrect()) {
            throw new IllegalTemperatureValueException("Temperature cannot be less than -273C");
        }
        if (temperatureSeries.length == 0) {
            double[] r = new double[1];
            r[0] = 0;
            return r;
        }
        int k = 0;
        for (int i = 0; i < temperatureSeries.length; i++) {
            if (temperatureSeries[i] < tempValue) {
                k++;
            }
        }
        double[] res = new double[k];
        for (int i = temperatureSeries.length-1; i >= 0; i--) {
            if (temperatureSeries[i] < tempValue) {
                res[k - 1] = temperatureSeries[i];
                k--;
            }
        }
        return res;
    }

    public double[] findTempsGreaterThen(double tempValue) throws IllegalTemperatureValueException {
        if (!checkCorrect()) {
            throw new IllegalTemperatureValueException("Temperature cannot be less than -273C");
        }
        if (temperatureSeries.length == 0) {
            double[] r = new double[1];
            r[0] = 0;
            return r;
        }
        int k = 0;
        for (int i = 0; i < temperatureSeries.length; i++) {
            if (temperatureSeries[i] >= tempValue) {
                k++;
            }
        }
        double[] res = new double[k];
        for (int i = temperatureSeries.length-1; i >= 0; i--) {
            if (temperatureSeries[i] >= tempValue) {
                res[k - 1] = temperatureSeries[i];
                k--;
            }
        }
        return res;
    }

    public double[] forecatsTemp() throws IllegalTemperatureValueException {
        if (!checkCorrect()) {
            throw new IllegalTemperatureValueException("Temperature cannot be less than -273C");
        }
        if (temperatureSeries.length == 0) {
            double[] r = new double[1];
            r[0] = 0;
            return r;
        }
        return new double[1];
    }
}
